package main

import (
	"fmt"
	"io"
	"net"
)

const (
	pubip   = ""
	pubport = 8081
	pxyip   = ""
	pxyport = 4443
	addr    = "127.0.0.1:80"
)

func main() {
	pxylisten, err := net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP(pxyip), pxyport, ""})
	if err != nil {
		fmt.Println("监听端口失败:", err.Error())
		return
	}
	publisten, err := net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP(pubip), pubport, ""})
	if err != nil {
		fmt.Println("监听端口失败:", err.Error())
		return
	}
	fmt.Println("已初始化连接，等待客户端连接...")
	PxyConn(pxylisten, publisten)
}
func PxyConn(pxylisten *net.TCPListener, publisten *net.TCPListener) {
	for {
		pxyconn, err := pxylisten.AcceptTCP()
		if err != nil {
			fmt.Println("接受客户端连接异常:", err.Error())
			continue
		}
		defer pxyconn.Close()
		fmt.Println("代理连接来自:", pxyconn.RemoteAddr().String())
		pubconn, err := publisten.AcceptTCP()
		if err != nil {
			fmt.Println("公网连接异常:", err.Error())
			continue
		}
		defer pubconn.Close()
		fmt.Println("公网连接来自:", pubconn.RemoteAddr().String())
		go func() {
			_, err := io.Copy(pxyconn, pubconn)
			if err != nil {
				fmt.Println("读取客户端数据错误:", err.Error())
			}
			//fmt.Println("复制字节：", c)
		}()
		go func() {
			_, err := io.Copy(pubconn, pxyconn)
			if err != nil {
				fmt.Println("读取客户端数据错误:", err.Error())
			}
			//fmt.Println("复制字节：", c)
		}()
	}
}

/*func PubConn(listen *net.TCPListener) {
	for {
		conn, err := listen.AcceptTCP()
		if err != nil {
			fmt.Println("公网连接异常:", err.Error())
			continue
		}
		defer conn.Close()
		fmt.Println("公网连接来自:", conn.RemoteAddr().String())
		//pxy := <-pxyconn
		go func() {
			_, err := io.Copy(pxy, conn)
			if err != nil {
				fmt.Println("读取客户端数据错误:", err.Error())
			}
			//fmt.Println("复制字节：", c)
		}()
		go func() {
			_, err := io.Copy(conn, pxy)
			if err != nil {
				fmt.Println("读取客户端数据错误:", err.Error())
			}
			//fmt.Println("复制字节：", c)
		}()
	}
}*/

func Server(listen *net.TCPListener) {
	for {
		conn, err := listen.AcceptTCP()
		if err != nil {
			fmt.Println("接受客户端连接异常:", err.Error())
			continue
		}
		defer conn.Close()
		fmt.Println("客户端连接来自:", conn.RemoteAddr().String())
		prvconn, err := net.Dial("tcp", addr)
		if err != nil {
			fmt.Println("连接服务端失败:", err.Error())
			return
		}
		fmt.Println("已连接服务器")
		defer prvconn.Close()
		go func() {
			buf := make([]byte, 32*1024)
			written := int64(0)
			for {
				nr, er := conn.Read(buf)
				if nr > 0 {
					nw, ew := prvconn.Write(buf[0:nr])
					if nw > 0 {
						written += int64(nw)
						fmt.Println("发送数据：", written)
					}
					if ew != nil {
						break
					}
					if nr != nw {
						break
					}
				}
				if er == io.EOF {
					fmt.Println("发送EOF")
					break
				}
				if er != nil {
					break
				}
			}
			//fmt.Println("发送数据：", written)
			/*i, err := conn.Read(data)
			fmt.Println("客户端发来数据:", i)
			if err != nil {
				fmt.Println("读取客户端数据错误:", err.Error())
			}
			prvconn.Write(data[:i])*/
		}()
		go func() {
			buf := make([]byte, 32*1024)
			written := int64(0)
			for {
				nr, er := prvconn.Read(buf)
				if nr > 0 {
					nw, ew := conn.Write(buf[0:nr])
					if nw > 0 {
						written += int64(nw)
						fmt.Println("读取数据：", written)
					}
					if ew != nil {
						break
					}
					if nr != nw {
						break
					}
				}
				if er == io.EOF {
					fmt.Println("读取EOF")
					break
				}
				if er != nil {
					err = er
					break
				}
			}
			//fmt.Println("读取数据：", written)
			/*data := make([]byte, 32*1024)
			c, err := prvconn.Read(data)
			if err != nil && err != io.EOF {
				fmt.Println("读取数据失败:", err.Error())
			} else {
				fmt.Println("数据长度：", c)
			}
			conn.Write(data[:c])*/
		}()
		/*go func() {
			_, err := io.Copy(prvconn, conn)
			if err != nil {
				fmt.Println("读取客户端数据错误:", err.Error())
			}
			//fmt.Println("复制字节：", c)
		}()
		go func() {
			_, err := io.Copy(conn, prvconn)
			if err != nil {
				fmt.Println("读取客户端数据错误:", err.Error())
			}
			//fmt.Println("复制字节：", c)
		}()*/
	}
}

func PrivateConn(data []byte) ([]byte, error) {
	buf := make([]byte, 10)
	conn, err := net.Dial("tcp", addr)
	if err != nil {
		fmt.Println("连接服务端失败:", err.Error())
		return buf, err
	}
	//fmt.Println("已连接服务器")
	defer conn.Close()
	for {
		conn.Write(data)
		buf := make([]byte, 409600)
		c, err := conn.Read(buf)
		if err != nil && err != io.EOF {
			fmt.Println("读取数据失败:", err.Error())
			return buf, err
		} else {
			fmt.Println("数据长度：", c)
			return buf[:c], nil
		}
	}
}
